HAL OTFDEC migration: Typical use cases

This section provides information about typical HAL OTFDEC migration use cases from HAL1 APIs to HAL2 XSPI OTFDEC APIs.

In HAL2,The OTFDEC is managed as a core driver, and its wrapped by the HAL XSPI driver. For more details about the OTFDEC core APIs, please refer to HAL OTFDEC migration: List of applicable concepts.

HAL OTFDEC prerequisites configuration

Before using OTFDEC APIs, the XSPI interface must be initialized and configured, and the external flash memory must be ready for access. This is required because OTFDEC performs on-the-fly decryption on data read through XSPI from external memory.

For more details about OTFDEC prerequisites configurations, please refer to HAL XSPI typical use cases for migration.

Use case: region configuration and on-the-fly decryption

Description of usage

In HAL1, the HAL OTFDEC driver provides a set of unitary APIs that allow the user to configure the OTFDEC mode, region, and key. These APIs must be called in the correct sequence, as defined in the reference manual.

In HAL2, this sequence is fully abstracted by HAL_XSPI_OTFDEC_SetConfigRegion(), which configures the required mode, region start and end addresses, region nonce, firmware version and region key. This HAL2 function internally implements the correct sequence according to the reference manual.

In HAL1, the region is enabled within HAL_OTFDEC_RegionConfig(). In HAL2, HAL_XSPI_OTFDEC_SetConfigRegion() configures only the region, and on-the-fly decryption is started separately using HAL_XSPI_OTFDEC_StartRegionDecryption().

In HAL1, the region lock is performed within HAL_OTFDEC_RegionConfig(). In HAL2, a dedicated region configuration lock function is provided: HAL_XSPI_OTFDEC_LockRegionConfig(). This function must be called, if needed, after starting the region with HAL_XSPI_OTFDEC_StartRegionDecryption().

The key lock mechanism remains the same between HAL1 and HAL2, with only a minor naming change from HAL_OTFDEC_RegionKeyLock() to HAL_XSPI_OTFDEC_LockRegionKey().

Operation

HAL1

HAL2

Region configuration sequence

Uses unitary APIs to configure OTFDEC mode, region, and key. The APIs must be called in the correct sequence defined in the reference manual.

This sequence is abstracted by HAL_XSPI_OTFDEC_SetConfigRegion(), which configures mode, start/end addresses, region nonce, firmware version, and key according to the reference manual.

Region activation

Region is enabled by HAL_OTFDEC_RegionConfig().

HAL_XSPI_OTFDEC_SetConfigRegion() configures only the region. Decryption is started separately using HAL_XSPI_OTFDEC_StartRegionDecryption().

Region configuration lock

Region lock is performed inside HAL_OTFDEC_RegionConfig().

Region lock is performed using dedicated API HAL_XSPI_OTFDEC_LockRegionConfig() after HAL_XSPI_OTFDEC_StartRegionDecryption() when needed.

Key lock mechanism

Uses HAL_OTFDEC_RegionKeyLock().

Same mechanism with naming change to HAL_XSPI_OTFDEC_LockRegionKey().

Sequence diagram

@startuml
title HAL1 "OTFDEC Driver Usage Sequence Diagram"

participant "User Application" as App
participant "HAL1 OTFDEC Driver" as HAL1

== "OTFDEC Region #i Configuration" ==
App -> HAL1 : "HAL_OTFDEC_RegionSetMode()"
App -> HAL1 : "HAL_OTFDEC_RegionSetKey()"
App -> HAL1: HAL_OTFDEC_RegionKeyLock() [optional]
App -> HAL1 : "HAL_OTFDEC_RegionConfig()"
App -> HAL1 : "HAL_OTFDEC_RegionDisable()"
HAL1 --> App : "HAL_OK"
@enduml

Code snippet

HAL1

HAL2

OTFDEC_RegionConfigTypeDef config = {0};

uint32_t key_words[4] = { 0x71234567, 0x89ABCDEF, 0x71234567, 0x89ABCDEF };

config.StartAddress = 0x90000000U;
config.EndAddress = 0x90000FFFU;
config.Nonce[0] = 0xA5A5A5A5;
config.Nonce[1] = 0xC3C3C3C3;
config.Version = 0xDCBA;

/* Select read access mode for this region. */
HAL_OTFDEC_RegionSetMode(&hotfdec, OTFDEC_REGION1, OTFDEC_REG_MODE_INSTRUCTION_OR_DATA_ACCESSES);

/* Program the region encryption key. */
HAL_OTFDEC_RegionSetKey(&hotfdec, OTFDEC_REGION1, key_words);

/* Lock the region key against future changes. */
HAL_OTFDEC_RegionKeyLock(&hotfdec, OTFDEC_REGION1);

/* Apply region configuration and lock it. */
HAL_OTFDEC_RegionConfig(&hotfdec, OTFDEC_REGION1, &config, OTFDEC_REG_CONFIGR_LOCK_ENABLE);

/* Stop decryption for this region. */
HAL_OTFDEC_RegionDisable(&hotfdec, OTFDEC_REGION1);
hal_xspi_otfdec_config_t config = {0};
hal_xspi_otfdec_key_t key_config = {0};
uint32_t key_words[4] = { 0x71234567, 0x89ABCDEF, 0x71234567, 0x89ABCDEF };

config.start_address = 0x90000000U;
config.end_address = 0x90000FFFU;
config.nonce[0] = 0xA5A5A5A5;
config.nonce[1] = 0xC3C3C3C3;
config.version = 0xDCBA;

config.mode = HAL_XSPI_OTFDEC_MODE_ALL_READ_ACCESS;

key_config.p_key = key_words;
key_config.key_size_byte = HAL_XSPI_OTFDEC_KEY_SIZE_128BIT;

/* Configure region parameters and key material. */
HAL_XSPI_OTFDEC_SetConfigRegion(&hxspi, HAL_XSPI_OTFDEC_REGION_1, &config, &key_config);

/* Lock the key to prevent further updates. */
HAL_XSPI_OTFDEC_LockRegionKey(&hxspi, HAL_XSPI_OTFDEC_REGION_1);

/* Enable on-the-fly decryption on this region. */
HAL_XSPI_OTFDEC_StartRegionDecryption(&hxspi, HAL_XSPI_OTFDEC_REGION_1, HAL_XSPI_OTFDEC_IT_NONE);

/* Lock region configuration registers. */
HAL_XSPI_OTFDEC_LockRegionConfig(&hxspi, HAL_XSPI_OTFDEC_REGION_1);

/* Disable on-the-fly decryption on this region. */
HAL_XSPI_OTFDEC_StopRegionDecryption(&hxspi, HAL_XSPI_OTFDEC_REGION_1);

Use case: plaintext to ciphertext encryption

Sequence diagram

@startuml
participant "Application" as App
participant "OTFDEC HAL1" as HAL1

App -> HAL1: HAL_OTFDEC_RegionSetMode()
App -> HAL1: HAL_OTFDEC_RegionSetKey()
App -> HAL1: HAL_OTFDEC_RegionKeyLock() [optional]
App -> HAL1: HAL_OTFDEC_RegionConfig()
App -> HAL1: HAL_OTFDEC_EnableEnciphering()
App -> HAL1: HAL_OTFDEC_Cipher()

note left of App
"Ciphered data is ready,
the user can copy it to
an external memory"
end note
@enduml

Code snippet

HAL1

HAL2

#define DATA_SIZE_BYTE 16U

OTFDEC_RegionConfigTypeDef config = {0};

uint32_t key_words[4] = { 0x00112233U, 0x44556677U, 0x8899AABBU, 0xCCDDEEFFU };
uint32_t plain_data[4] = { 0x30201000U, 0x70605040U, 0xB0A09080U, 0x01F0E0D0U };
uint32_t cipher_data[4] = {0};

config.StartAddress = 0x90000000U;
config.EndAddress = 0x90000FFFU;
config.Nonce[0] = 0xA5A5A5A5;
config.Nonce[1] = 0xC3C3C3C3;
config.Version = 0xDCBA;

/* Configure region access mode. */
HAL_OTFDEC_RegionSetMode(&hotfdec, OTFDEC_REGION1, HAL_OTFDEC_MODE_ALL_READ_ACCESS);

/* Program region key material. */
HAL_OTFDEC_RegionSetKey(&hotfdec, OTFDEC_REGION1, key_words);

/* Optionally lock the key to prevent further updates. */
HAL_OTFDEC_RegionKeyLock(&hotfdec, OTFDEC_REGION1);

/* Apply region address/nonce/version configuration. */
HAL_OTFDEC_RegionConfig(&hotfdec, OTFDEC_REGION1, &config, OTFDEC_REG_CONFIGR_LOCK_ENABLE);

/* Enable enciphering mode before calling cipher API. */
HAL_OTFDEC_EnableEnciphering(&hotfdec);

/* Encrypt plaintext buffer into cipher_data. */
HAL_OTFDEC_Cipher(&hotfdec, OTFDEC_REGION1, plain_data, cipher_data, DATA_SIZE_BYTE, config.StartAddress);
#define DATA_SIZE_BYTE 16U

hal_xspi_otfdec_config_t config = {0};
hal_xspi_otfdec_key_t key_config = {0};
uint32_t key_words[4] = { 0x00112233U, 0x44556677U, 0x8899AABBU, 0xCCDDEEFFU };
uint32_t plain_data[4] = { 0x30201000U, 0x70605040U, 0xB0A09080U, 0x01F0E0D0U };
uint32_t cipher_data[4] = {0};

config.nonce[0] = 0xA5A5A5A5;
config.nonce[1] = 0xC3C3C3C3;
config.start_address = 0x90000000U;
config.end_address = 0x90000FFFU;
config.version = 0xDCBA;

config.mode = HAL_XSPI_OTFDEC_MODE_ALL_READ_ACCESS;

key_config.p_key = key_words;
key_config.key_size_byte = HAL_XSPI_OTFDEC_KEY_SIZE_128BIT;
/* Configure region parameters and key material. */
HAL_XSPI_OTFDEC_SetConfigRegion(&hxspi, HAL_XSPI_OTFDEC_REGION_1, &config, &key_config);

/* Optionally lock the key against future changes. */
HAL_XSPI_OTFDEC_LockRegionKey(&hxspi, HAL_XSPI_OTFDEC_REGION_1);

/* Encrypt plaintext into cipher buffer.
   XSPI must already be configured in memory-mapped mode. */
HAL_XSPI_OTFDEC_Encrypt(&hxspi,HAL_XSPI_OTFDEC_REGION_1,plain_data,cipher_data,
                        DATA_SIZE_BYTE, config.start_address,
                        HAL_XSPI_OTFDEC_IT_NONE);